//
//  WKWebViewController.swift
//  DoShare
//
//  Created by sdyx on 2019/7/24.
//  Copyright © 2019 eetrust. All rights reserved.
//

/*
    func test() {
        let fileURL = URL.init(fileURLWithPath: Bundle.main.path(forResource: "jsdemo", ofType: "html")!)
        let request = URLRequest.init(url: fileURL, cachePolicy: .reloadIgnoringLocalCacheData, timeoutInterval: 15.0)
        let web = WKWebViewController()
        web.urlRequest = request
        FCurrentNav()?.pushViewController(web, animated: true)
    }
 */

import UIKit
import WebKit
import SnapKit
import SVProgressHUD
import CryptoKit

class WKWebViewController: UIViewController {
    
    var wkTitle: String?
    var urlRequest: URLRequest?
    var canSave: Bool = false
    
    private var fileURL: URL?
    private var leftBarButton: UIBarButtonItem!
    private var leftBarButtonSecond: UIBarButtonItem!
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        setupUI()
        addKVOObserver()
        loadRequest()
    }
    
    override var preferredStatusBarStyle: UIStatusBarStyle { return .lightContent }

    override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) {
        if keyPath == "estimatedProgress" {
            progressView.isHidden = false
            progressView.setProgress(Float(wkWebView.estimatedProgress), animated: true)
            if wkWebView.estimatedProgress >= 1 {
                UIView.animate(withDuration: 0.5, animations: {
                    self.progressView.isHidden = true
                }) { (finished) in
                    self.progressView.setProgress(0.0, animated: false)
                }
            }
        } else if keyPath == "title" {
            navigationItem.title = wkWebView.title ?? wkTitle
        } else if keyPath == "canGoBack" {
            if wkWebView.canGoBack {
                navigationItem.leftBarButtonItems = [leftBarButton, leftBarButtonSecond]
            } else {
                navigationItem.leftBarButtonItems = [leftBarButton]
            }
        } else {
            super.observeValue(forKeyPath: keyPath, of: object, change: change, context: context)
        }
    }
    
    func load(_ urlRequest: URLRequest) {
        wkWebView.load(urlRequest)
    }
    
    func load(_ path: String) {
        let url = URL(fileURLWithPath: path)
        fileURL = url
        wkWebView.loadFileURL(url, allowingReadAccessTo: Bundle.main.bundleURL)
        if url.pathExtension == "txt" {
            if let data = try? Data(contentsOf: url) {
                wkWebView.load(data, mimeType: "text/plain", characterEncodingName: "UTF-8", baseURL: URL(fileURLWithPath: NSTemporaryDirectory()))
            }
        }
    }
    
    // MARK: - private
    
    private func loadRequest() {
        guard let request = urlRequest else {
            MyLog("urlRequest为空")
            return
        }
        wkWebView.load(request)
    }
    
    private func setupUI() {
        setupNav()
        view.backgroundColor = .systemBackground
        view.addSubview(wkWebView)
        view.addSubview(progressView)
        
        wkWebView.snp.makeConstraints { (make) in
            make.top.right.bottom.left.equalTo(self.view)
        }
        
        progressView.snp.makeConstraints { (make) in
            // TODO: 调整距离
            make.top.equalTo(wkWebView).offset(88)
            make.left.right.equalTo(wkWebView)
            make.height.equalTo(3.5)
        }
    }
    
    private func setupNav() {
        leftBarButton = UIBarButtonItem(image: UIImage(named: "nav_back_icon"), style: .plain, target: self, action: #selector(back))
        leftBarButtonSecond = UIBarButtonItem(image: UIImage(named: "nav_x_icon"), style: .plain, target: self, action: #selector(close))
        navigationItem.leftBarButtonItems = [leftBarButton]
        
        if canSave {
            let barBtn = UIBarButtonItem(title: "保存", style: .plain, target: self, action: #selector(more))
            barBtn.setTitleTextAttributes([NSAttributedString.Key.font : kNavBarBtnFont], for: .normal)
            navigationItem.rightBarButtonItem = barBtn
        }
    }
    
    @objc private func back() {
        if wkWebView.canGoBack {
            wkWebView.goBack()
        } else {
            close()
        }
    }

    @objc private func close() {
        navigationController?.setNavigationBarHidden(false, animated: true)
        navigationController?.popViewController(animated: true)
    }
    
    @objc private func more() {
        guard let fileURL = fileURL else { return }
        documentInteraction.url = fileURL
        documentInteraction.presentOpenInMenu(from: CGRect.zero, in: self.view, animated: true)
    }
    
    private func addKVOObserver() {
        wkWebView.addObserver(self, forKeyPath: "estimatedProgress", options: [.new, .old], context: nil)
        wkWebView.addObserver(self, forKeyPath: "canGoBack", options: [.new, .old], context: nil)
        wkWebView.addObserver(self, forKeyPath: "title", options: [.new, .old], context: nil)
    }
    
    // MARK: - lazy
    
    lazy var wkWebView: WKWebView = {
        let wb = WKWebView()
        wb.uiDelegate = self
        wb.navigationDelegate = self
        wb.backgroundColor = .white
        wb.autoresizingMask = UIView.AutoresizingMask(rawValue: 1|4)
        wb.isMultipleTouchEnabled = true
        wb.autoresizesSubviews = true
        wb.scrollView.alwaysBounceVertical = true
        wb.allowsBackForwardNavigationGestures = true
        wb.configuration.preferences.setValue(true, forKey: "allowFileAccessFromFileURLs")
        return wb
    }()
    
    lazy var progressView: UIProgressView = {
        let pv = UIProgressView()
        pv.progressTintColor = UIColor(hexString: "#85CA6F")
        pv.trackTintColor = .clear
        return pv
    }()
    
    lazy var documentInteraction: UIDocumentInteractionController = {
        let docu = UIDocumentInteractionController()
        docu.delegate = self;
        return docu
    }()
    
    deinit {
        wkWebView.removeObserver(self, forKeyPath: "title")
        wkWebView.removeObserver(self, forKeyPath: "canGoBack")
        wkWebView.removeObserver(self, forKeyPath: "estimatedProgress")
    }
}

extension WKWebViewController: WKNavigationDelegate, WKUIDelegate {
    
    func webView(_ webView: WKWebView, decidePolicyFor navigationAction: WKNavigationAction, decisionHandler: @escaping (WKNavigationActionPolicy) -> Void) {
        if navigationAction.targetFrame == nil {
            wkWebView.load(navigationAction.request)
        }
        decisionHandler(.allow)
    }
    
    // 解决网页无法跳转的问题
    // 需要新打开页面时
    func webView(_ webView: WKWebView, createWebViewWith configuration: WKWebViewConfiguration, for navigationAction: WKNavigationAction, windowFeatures: WKWindowFeatures) -> WKWebView? {
        if navigationAction.targetFrame == nil ||  !(navigationAction.targetFrame?.isMainFrame ?? false) {
            wkWebView.load(navigationAction.request)
        }
        
        return nil
    }
    
    // 加载完成
    func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {
        if let title = webView.title, title != "" {
            navigationItem.title = title
        } else {
            navigationItem.title = wkTitle
        }
    }
    
    // 加载失败
    func webView(_ webView: WKWebView, didFail navigation: WKNavigation!, withError error: Error) {
        MyLog("wkwebview_加载失败：\(error)")
    }
    
    // 解决因SSL证书引起的网页空白问题
    func webView(_ webView: WKWebView, didReceive challenge: URLAuthenticationChallenge, completionHandler: @escaping (URLSession.AuthChallengeDisposition, URLCredential?) -> Void) {
        if challenge.protectionSpace.authenticationMethod == NSURLAuthenticationMethodServerTrust {
            let card = URLCredential(trust: challenge.protectionSpace.serverTrust!)
            completionHandler(URLSession.AuthChallengeDisposition.useCredential,card)
        } else {
            completionHandler(.performDefaultHandling, nil)
        }
    }
}

extension WKWebViewController: UIDocumentInteractionControllerDelegate {
    func documentInteractionControllerViewControllerForPreview(_ controller: UIDocumentInteractionController) -> UIViewController {
        return self
    }
}

